package com.light.modules.admin.system.service;

import java.util.*;
import java.util.Objects;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.light.modules.admin.common.util.FreemarkUtil;
import com.light.modules.admin.common.util.StringUtil;
import com.light.modules.admin.common.util.UrlUtil;
import com.light.modules.admin.system.model.Menu;
import com.light.modules.admin.system.model.MenuBtn;
import com.light.modules.admin.system.model.MenuDatarule;
import com.light.modules.admin.system.model.SysUser;

/**
 * 登陆、权限业务
 *
 * @author 钟世云 2016.2.5
 */
public class LoginService {
    private List<Menu> allMenuList;
    private List<Menu> userMenuList;

    /**
     * 获得用户菜单
     */
    public List<Menu> getUserMenu(SysUser user) {
        //TODO 在这初始化成员变量，有问题
        allMenuList = Menu.me.findAll();
        userMenuList = Menu.me.findByUser(user);
        //获取每一个菜单的父菜单链
        Set<Menu> chainSet = Sets.newHashSet();
        userMenuList.stream().forEach(menu -> {
            chainSet.add(menu);
            getPChain(allMenuList, menu, chainSet);
        });
        //排序
        List<Menu> chainList = Lists.newArrayList(chainSet);
        chainList.sort((o1, o2) -> o1.get("order_num") == null || o2.get("order_num") == null
                || o1.getInt("order_num") < o2.getInt("order_num") ? -1 : 0);
        formatSubMenu(chainList);
        List<Menu> result = Lists.newArrayList();
        chainList.stream().forEach(item -> result.add(item));
        return result;
    }

    /**
     * 获得无权限访问的url（页面权限）
     */
    public List<String> getNoAuthUrl() {
        List<String> urlList = Lists.newArrayList();
        for (Menu menu1 : allMenuList) {
            boolean flag = true;
            for (Menu menu2 : userMenuList) {
                if (menu1.getInt("id") == menu2.getInt("id")) {
                    flag = false;
                    break;
                }
            }
            if (flag && StringUtil.isNotEmpty(menu1.getStr("menu_url"))) {
                urlList.add(menu1.getStr("menu_url"));
            }
        }
        return urlList;
    }

    /**
     * 按钮权限
     */
    public Map<String, Object> getNoAuthBtnUrl(SysUser user) {
        Map<String, Object> result = Maps.newHashMap();
        Map<Integer, Menu> userMenuMap = Maps.newHashMap();
        userMenuList.stream().forEach(menu->userMenuMap.put(menu.getInt("id"), menu));
        List<String> btnUrlList = Lists.newArrayList();
        //获得用户没有权限的按钮
        List<MenuBtn> _allMenuList = Lists.newArrayList(MenuBtn.me.findAll());
        _allMenuList.removeAll(MenuBtn.me.findByUser(user));
        List<MenuBtn> userBtnList = Lists.newArrayList(_allMenuList);

        Map<String, String> pageBtnMap = Maps.newHashMap();
        for (MenuBtn menuBtn : userBtnList) {
            Menu menu = userMenuMap.get(menuBtn.getInt("menu_id"));
            if (Objects.isNull(menu)) {    //有按钮权限，无菜单权限
                continue;
            }
            String methodName = menuBtn.getStr("method_name");
            String menuUrl = menu.getStr("menu_url");
            menuUrl = UrlUtil.removeUrlParam(menuUrl);    //去掉参数部分
            if (StringUtil.isNotEmpty(methodName) && StringUtil.isNotEmpty(menuUrl)) {
                for (String method : methodName.split(",")) {
                    method = ("/" + method).replaceAll("//+", "/");
                    if (method.lastIndexOf("/") > 0) {
                        btnUrlList.add(method);
                    } else {
                        btnUrlList.add(UrlUtil.formatBaseUrl(menuUrl) + method);
                    }
                }
                //页面按钮
                String btnName = pageBtnMap.get(menuUrl);
                if (StringUtil.isEmpty(btnName)) {
                    btnName = menuBtn.getStr("class_name");
                } else {
                    btnName = btnName + "," + menuBtn.getStr("class_name");
                }
                pageBtnMap.put(menuUrl, btnName);
            }
        }
        result.put("btnUrlList", btnUrlList);
        result.put("pageBtnMap", pageBtnMap);
        return result;
    }

    /**
     * 数据权限
     */
    public Map<String, List<MenuDatarule>> getNoAuthDatarule(SysUser user) {
        Map<Integer, Menu> userMenuMap = Maps.newHashMap();

        for (Menu menu : userMenuList) {
            userMenuMap.put(menu.getInt("id"), menu);
        }

        Map<String, List<MenuDatarule>> pageDataruleMap = new HashMap<String, List<MenuDatarule>>();
        List<MenuDatarule> userDataruleList = MenuDatarule.me.findByUser(user);

        //变量支持
        for (MenuDatarule menuDatarule : userDataruleList) {
            String value = menuDatarule.get("value");
            Map<String, Object> data = Maps.newHashMap();
            //TODO 变量处理，此处可以加其它数据
            data.put("user", user);
            menuDatarule.set("value", FreemarkUtil.parse(value, data));
        }

        for (MenuDatarule menuDatarule : userDataruleList) {
            String menuUrl = userMenuMap.get(menuDatarule.getInt("menu_id")).getStr("menu_url");
            if (StringUtil.isNotEmpty(menuUrl)) {
                menuUrl = UrlUtil.formatBaseUrl(menuUrl);
                List<MenuDatarule> dataruleList = pageDataruleMap.get(menuUrl);
                if (dataruleList == null) {
                    dataruleList = new ArrayList<MenuDatarule>();
                }
                dataruleList.add(menuDatarule);
                pageDataruleMap.put(menuUrl, dataruleList);
            }
        }
        return pageDataruleMap;
    }


    /**
     * 获得菜单的所有父菜单
     */
    public void getPChain(Collection<Menu> list, Menu menu, Set<Menu> chainlist) {
        for (Menu m : list) {
            if (menu.getInt("parent_id") == m.getInt("id")) {
                chainlist.add(m);
                getPChain(list, m, chainlist);
            }
        }
    }

    /**
     * 按上下级格式化数据菜单数据
     */
    private void formatSubMenu(Collection<Menu> list) {
        for (Menu menu1 : list) {
            for (Menu menu2 : list) {
                if (Objects.equals(menu1.getInt("id"), menu2.getInt("parent_id"))) {
                    menu1.getSubMenuList().add(menu2);
                }
            }
        }
    }

    /**
     * 获得两个list之元素之差(list1 - list2)
     */
    private List<MenuBtn> getDifference(List<MenuBtn> list1, List<MenuBtn> list2) {
        List<MenuBtn> result = Lists.newArrayList();
        for (MenuBtn menuBtn1 : list1) {
            boolean flag = true;
            for (MenuBtn menuBtn2 : list2) {
                if (Objects.equals(menuBtn1.getInt("id"),menuBtn2.getInt("id"))) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                result.add(menuBtn1);
            }
        }
        return result;
    }

}
